package org.jeecg.modules.demo.crm.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.crm.dto.CProjectApplicationDTO;
import org.jeecg.modules.demo.crm.entity.*;
import org.jeecg.modules.demo.crm.mapper.*;
import org.jeecg.modules.demo.crm.service.ICProjectApplicationService;
import org.jeecg.modules.demo.crm.service.ICProjectStatusLogService;
import org.jeecg.modules.demo.crm.service.ICSubProjectService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 项目信息
 * @Author: jeecg-boot
 * @Date:   2025-05-28
 * @Version: V1.0
 */
@Service
public class CProjectApplicationServiceImpl extends ServiceImpl<CProjectApplicationMapper, CProjectApplication> implements ICProjectApplicationService {

    @Autowired
    CSubProjectMapper cSubProjectMapper;
    @Autowired
    CProjectApplicationMapper cProjectApplicationMapper;

    @Autowired
    CContractorInfoMapper cContractorInfoMapper;

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private CSubProjectStatusLogMapper cSubProjectStatusLogMapper;

    @Autowired
    private ICProjectStatusLogService cProjectStatusLogService;

    @Autowired
    private CProjectStatusLogMapper cProjectStatusLogMapper;

    @Autowired
    CPaymentRecordMapper cPaymentRecordMapper;

    @Autowired
    CPaymentRequestMapper cPaymentRequestMapper;

    @Autowired
    CInvoiceApplyMapper cInvoiceApplyMapper;

    @Autowired
    CPaymentInvoiceMapper cPaymentInvoiceMapper;

    @Autowired
    CContractMapper cContractMapper;

    @Autowired
    CAdditionalRequestMapper cAdditionalRequestMapper;

    @Autowired
    CReimbursementMapper cReimbursementMapper;

    @Autowired
    CLibraryMapper cLibraryMapper;

    @Autowired
    CContractingUnitMapper cContractingUnitMapper;

    @Autowired
    CCompanyInfoMapper cCompanyInfoMapper;

    @Autowired
    CProjectHeadQuotesMapper cProjectHeadQuotesMapper;



    @Override
    public CProjectApplicationDTO getOrderInfo(String id, LoginUser sysUser) {

       if(sysUser.getRoleCode().contains("admin") || sysUser.getRoleCode().contains("项目经理") || 1==1){
            CProjectApplication projectApplication = cProjectApplicationMapper.selectById(id);
            if(projectApplication == null){
                throw new JeecgBootException("总项目不存在");
            }
            CProjectApplicationDTO projectApplicationDTO = new CProjectApplicationDTO();
            BeanUtils.copyProperties(projectApplication, projectApplicationDTO);
            if(projectApplicationDTO.getManageFee() == null){
                projectApplicationDTO.setManageFee(BigDecimal.ZERO);
            }


           List<CSubProject> subProjectList = cSubProjectMapper.findByProjectId(projectApplicationDTO.getId());
            if(subProjectList == null){
                throw new JeecgBootException("项目不存在");
            }
            //查询库
           CLibrary cLibrary = cLibraryMapper.selectById(projectApplication.getLibraryId());
           projectApplicationDTO.setLibrary(cLibrary);

           //发包单位
           CContractingUnit cContractingUnit = cContractingUnitMapper.selectById(projectApplication.getContractingUnit());
           projectApplicationDTO.setContractingUnitVo(cContractingUnit);

           //总包主体
           CCompanyInfo cCompanyInfo = cCompanyInfoMapper.selectById(projectApplication.getCompanyInfoId());
           projectApplicationDTO.setCompanyInfo(cCompanyInfo);

           //合同
           List<CContract> contract = cContractMapper.findByProjectId(projectApplication.getId());
           projectApplicationDTO.setContract(contract);
           if(contract!= null && contract.size()>0){
               String idString = contract.stream()
                       .map(CContract::getId) // 获取每个对象的 id
                       .map(String::valueOf) // 将 id 转换为字符串
                       .collect(Collectors.joining(",")); // 使用逗号拼接
               projectApplicationDTO.setContractId(idString);
           }

           //质保金合计
           // totalWarranty
           //查询质保金 （合计）
           BigDecimal totalGuaranteeDeposit = cContractMapper.guaranteeDeposit(projectApplication.getId());
           projectApplicationDTO.setTotalGuaranteeDeposit(totalGuaranteeDeposit);


           //总项目报价记录
           BigDecimal totalProjectQuotation = cProjectHeadQuotesMapper.totalProjectQuotation(projectApplication.getId());
           projectApplicationDTO.setTotalProjectQuotation(totalProjectQuotation);
           //子项目
            projectApplicationDTO.setCSubProjectList(subProjectList);

            //登陆者信息
            LoginUser sysUserData = new LoginUser();
            sysUserData.setId(sysUser.getId());
            sysUserData.setUsername(sysUser.getUsername());
            sysUserData.setRoleCode(sysUser.getRoleCode());
            projectApplicationDTO.setSysUser(sysUserData);

            //查询状态
            List<CProjectStatusLog> projectLog = cProjectStatusLogMapper.findListByProjectId(projectApplicationDTO.getId());
            projectApplicationDTO.setProjectStatusLogList(projectLog);

           //合同总额(含税金额)
           BigDecimal contractPrice = cContractMapper.contractPrice(projectApplicationDTO.getId());
           projectApplicationDTO.setContractPrice(contractPrice);

           //报销费用
           BigDecimal reimbursement = cReimbursementMapper.reimbursement(projectApplicationDTO.getId());
           projectApplicationDTO.setReimbursement(reimbursement);

            //收款合计
           BigDecimal totalReceipts = cPaymentRecordMapper.getTotalAmount(projectApplication.getId());
           projectApplicationDTO.setTotalReceipts(totalReceipts);

           //付款总金额
           BigDecimal paymentTotal = cPaymentRequestMapper.getTotalAmount(projectApplication.getId());
           projectApplicationDTO.setPaymentTotal(paymentTotal);

           //收票金额
           BigDecimal receiptsTotal = cPaymentInvoiceMapper.getTotalAmount(projectApplication.getId());
           projectApplicationDTO.setReceiptsTotal(receiptsTotal);


            //收票税额
           BigDecimal receiptsTaxTotal = cPaymentInvoiceMapper.getReceiptsTaxTotal(projectApplication.getId());
           projectApplicationDTO.setReceiptsTaxTotal(receiptsTaxTotal);

           //收票合计(元)
           BigDecimal receiptsAndTaxTotal = receiptsTaxTotal.add(receiptsTotal);
           projectApplicationDTO.setReceiptsAndTaxTotal(receiptsAndTaxTotal);




           //开票金额
           BigDecimal invoicingTotal = cInvoiceApplyMapper.getTotalAmount(projectApplication.getId());
           projectApplicationDTO.setInvoicingTotal(invoicingTotal);

           //开票合计税额
           BigDecimal totalTaxAmount = cInvoiceApplyMapper.getTotalTaxAmount(projectApplication.getId());
           projectApplicationDTO.setTotalTaxAmount(totalTaxAmount);

           //开票合计(元)
           BigDecimal totalInvoiceTax = totalTaxAmount.add(invoicingTotal);
           projectApplicationDTO.setTotalInvoiceTax(totalInvoiceTax);

           //未开票金额 (施工合同金额-开票合计)
           BigDecimal uninvoicedAmount=contractPrice.subtract(totalInvoiceTax);
           projectApplicationDTO.setUninvoicedAmount(uninvoicedAmount);



           //未收款
           BigDecimal uncollectedPayment = contractPrice.subtract(totalReceipts);
           projectApplicationDTO.setUncollectedPayment(uncollectedPayment);

           //总子项目合同金额（含税）
           BigDecimal subProjectAmount = cContractMapper.contractSubProjectPrice(projectApplication.getId());
           projectApplicationDTO.setSubProjectAmount(subProjectAmount);


           //应交票税(元)（开票税额-收票税额）
           BigDecimal invoiceTaxPayable = totalTaxAmount.subtract(receiptsTaxTotal);
           projectApplicationDTO.setInvoiceTaxPayable(invoiceTaxPayable);

           //可用余额 (收款金额-付款金额-报销-管理费-应交票税)
           BigDecimal availableBalance = totalReceipts.subtract(paymentTotal)
                   .subtract(reimbursement).subtract(projectApplicationDTO.getManageFee()).subtract(invoiceTaxPayable).setScale(2, RoundingMode.HALF_UP);
           projectApplicationDTO.setAvailableBalance(availableBalance);

           //项目未收款金额(施工合同金额-项目收款)
           BigDecimal projectUncollectedPayment = contractPrice.subtract(totalReceipts);
           projectApplicationDTO.setProjectUncollectedPayment(projectUncollectedPayment);

           //子项未付款金额(子项目合同金额合计-付款金额)
           BigDecimal subProjectNonPayment = subProjectAmount.subtract(paymentTotal);
           projectApplicationDTO.setSubProjectNonPayment(subProjectNonPayment);


           // 未收票金额 (子项目合同金额（含税）- 收票合计含税（含税）)
           BigDecimal uncollectedAmount = subProjectAmount.subtract(receiptsAndTaxTotal);
           projectApplicationDTO.setUncollectedAmount(uncollectedAmount);

           ///-------图标表格--------
            //开票进度（开票的票税合计/施工金额）
           BigDecimal invoicingProgress = new BigDecimal("0");
           if(contractPrice != null && contractPrice.compareTo(BigDecimal.ZERO) > 0){
               invoicingProgress = totalInvoiceTax.divide(contractPrice,4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_DOWN);
           }
           projectApplicationDTO.setInvoicingProgress(invoicingProgress);

           //收款进度（收款金额合计/施工金额）
           projectApplicationDTO.setReceivingProgress(BigDecimal.ZERO);
           if(totalReceipts.compareTo(BigDecimal.ZERO) != 0 && contractPrice.compareTo(BigDecimal.ZERO) != 0){
               BigDecimal receivingProgress = totalReceipts.divide(contractPrice,4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_DOWN);
               projectApplicationDTO.setReceivingProgress(receivingProgress);
           }

           //付款进度（付款总金额/子项目合同金额）
           projectApplicationDTO.setPaymentProgress(BigDecimal.ZERO);
           if(subProjectAmount.compareTo(BigDecimal.ZERO) != 0 && paymentTotal.compareTo(BigDecimal.ZERO) != 0){
               BigDecimal paymentProgress = paymentTotal.divide(subProjectAmount,4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_DOWN);
               projectApplicationDTO.setPaymentProgress(paymentProgress);
           }

           //子项目进度 （子项目合同金额/总项目合同金额）
           projectApplicationDTO.setSubProjectProgress(BigDecimal.ZERO);
           if(subProjectAmount.compareTo(BigDecimal.ZERO) != 0 && contractPrice.compareTo(BigDecimal.ZERO) != 0){
               BigDecimal subProjectProgress = subProjectAmount.divide(contractPrice,4,BigDecimal.ROUND_DOWN).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_DOWN);
               projectApplicationDTO.setSubProjectProgress(subProjectProgress);
           }

           return projectApplicationDTO;
        }else {
            throw new JeecgBootException("无权限查看");
        }
    }

    @Override
    @Transactional
    public void installApplication(CProjectApplication cProjectApplication) {
        if(cProjectApplicationMapper.findProjectNumber(cProjectApplication.getProjectNumber()) != null){
            throw new JeecgBootException("合同编号重复!");
        }
        cProjectApplication.setProjectStatus("前期");
        if(StringUtils.isNotEmpty(cProjectApplication.getProjectContract())){
            //如果不为空 创建项目说明立项了
            cProjectApplication.setProjectStatus("立项");
        }
        cProjectApplicationMapper.insert(cProjectApplication);
        cProjectStatusLogService.updateStatus(cProjectApplication.getId(),"前期");
        if(StringUtils.isNotEmpty(cProjectApplication.getProjectContract())){
            cProjectStatusLogService.updateStatus(cProjectApplication.getId(),"立项");
        }
        //合同关联
        //cContractMapper.unbinding()
        String contractId = cProjectApplication.getContractId();
        if(contractId != null && contractId.length()>0){
            String[] contractIds = contractId.split(",");
            for (String id : contractIds) {

                CContract cContract = cContractMapper.selectById(id);
                cContract.setProjectId(cProjectApplication.getId());
                cContract.setSubProjectId(null);
                cContractMapper.updateById(cContract);
            }
        }

    }

    @Override
    public void updateApplication(CProjectApplication cProjectApplication) {
        CProjectApplication application = cProjectApplicationMapper.selectById(cProjectApplication.getId());
       /* if(!application.getProjectStatus().equals("前期")){
            throw new JeecgBootException("项目状态错误!");
        }*/
        if(StringUtils.isEmpty(cProjectApplication.getProjectContract())){
            cProjectApplication.setProjectNumber(application.getProjectNumber());
        }

        if(StringUtils.isNotEmpty(cProjectApplication.getProjectContract())){
            //如果不为空 创建项目说明立项了
            cProjectApplication.setProjectStatus("立项");
        }
        cProjectApplicationMapper.updateById(cProjectApplication);
        if(StringUtils.isNotEmpty(cProjectApplication.getProjectContract())){
            cProjectStatusLogService.updateStatus(cProjectApplication.getId(),"立项");
        }

        //合同关联
       /* cContractMapper.unbinding(cProjectApplication.getId());
        String contractId = cProjectApplication.getContractId();
        if(contractId != null && contractId.length()>0){
            String[] contractIds = contractId.split(",");
            for (String id : contractIds) {
                CContract cContract = cContractMapper.selectById(id);
                cContract.setProjectId(cProjectApplication.getId());
                cContract.setSubProjectId(null);
                cContractMapper.updateById(cContract);
            }
        }*/

    }

    @Override
    public void toggleFavorite(CProjectApplication cProjectApplication) {
        CProjectApplication projectApplication1 = cProjectApplicationMapper.selectById(cProjectApplication.getId());
        if(projectApplication1.getIsFavorite() == 0){
            //查找最大的排序值
            Integer max = cProjectApplicationMapper.toggleFavoriteMax();
            projectApplication1.setIsFavorite(max + 1);
        }else {
            projectApplication1.setIsFavorite(0);
            cProjectApplicationMapper.updateById(projectApplication1);
        }
        cProjectApplicationMapper.updateById(projectApplication1);
    }
}
